import utime as time
import hmi_drv
import rtc
import sensor_interface
import m485Drv
import tfcard
import app_relay
import yun_network
import power
import led_drv
# import sleep_mode



sensor_instan = None
rtc_instan = None
collect_flag = 0
max_wait_time = 1    # 单位分钟

# 读取传感器数据回调
def collected_data_handler(sensor_name=None,**kwargs):
    global sensor_instan
    if not sensor_instan:
        print('sensor is not init')
        return []
    return sensor_instan.read_sensor(sensor_name, **kwargs)
# 从触摸屏读取RTC时间 
def rtc_handler(year=None, month=None, day=None, hour=None, minute=None, second=None):
    global rtc_instan
    # 如果传入了参数，则设置时间
    if year is not None:
        rtc_instan.set_time(year,month,day,hour,minute,second)
    d = rtc_instan.getRtcTime()
    # print("current RTC time:",d)
    return d

def main():
# 变量
    global sensor_instan,max_wait_time
    global rtc_instan,collect_flag

# 网络注册
    yun_network.connect_network()
    led_drv.led_on("LED2")
# 初始化系统rtc
    rtc_instan = rtc.SysRtc()
# 创建传感器实例
    soil_sensor = m485Drv.ModeBusRtu()
# 创建tf卡接口实例
    tf = tfcard.SetTfCard(rtc_instan)
# 创建触摸屏实例
    uart_proj = hmi_drv.HmiDrver()
# 注册串口屏接收数据回调
    uart_proj.register_calback(collected_data_handler)
# 注册触摸屏RTC接口回调
    uart_proj.register_rtc_calback(rtc_handler)
# 注册tf卡接口回调
    uart_proj.register_tf_calback(tf)
# 获取串口屏RTC时间
    # uart_proj.ReadRTC()
# 创建传感器接口实例
    sensor_instan = sensor_interface.SensorInterface()
# 注册传感器参数数据
    #方式1：注册单个传感器
    # sensor_instan.register_sensor(soil =(soil_sensor,'read_soil_sensor')) 
    # 方式2：注册多实例传感器（适合大量相同类型但参数不同的传感器）
    sensor_instan.register_sensor(
                soil={
                        "sensor": soil_sensor,             
                        "method": "read_virtual_soil_sensor",     # 虚拟函数read_virtual_soil_sensor/实际函数read_soil_sensor
                        "instances": [
                                        {"name": "No1", "params": {"addr": 1}},
                                        {"name": "No2", "params": {"addr": 2}},
                                        {"name": "No3", "params": {"addr": 3}},
                                        {"name": "No4", "params": {"addr": 4}},
                                        {"name": "No5", "params": {"addr": 5}},
                                        {"name": "No6", "params": {"addr": 6}}
                                    ]
                    }
                )
 
    last_collection_time = None
    last_next_time = None 
    
    # 进入低功耗
    yun_network.set_flight_mode(1) # 1: 飞行模式 2：普通模式
    led_drv.led_off("LED2")
    # sleep_mode.sys_sleep(1)
    
# 主循环
    while True:
        # 读取方式1：读取所有传感器
        # data  = collected_data_handler()
        # 读取方式2：读取特定传感器
        # soil1_data = collected_data_handler('soil1')
        # 读取方式3：临时指定参数（覆盖注册时的参数）
        # 获取当前时间
        # 获取当前时间
        if uart_proj.get_collect_flag():
            # 直接从RTC获取时间字符串
            current_time_tuple = rtc_instan.sys_rtc()
            # 只在需要时计算下次采集时间
            if last_collection_time is None or current_time_tuple != last_collection_time:
                interval = uart_proj.get_interval()
                # 使用新的函数，直接传入时间字符串
                next_time, wait_seconds = rtc_instan.get_next_collection_time_with_time(int(interval))
                # next_time, wait_seconds = rtc_instan.get_next_collection_time_with_time(300)
                print("Wait seconds:", wait_seconds)
                # print("Next time: ", next_time)  # 调试信息
                # 判断是否到了采集时间（容忍2秒误差）
                if wait_seconds <= 7 and next_time != last_next_time:
                    # 低功耗模式
                    # sleep_mode.voltage_3v3(1)
                    # tf.mount_sd_card()
                 
                    led_drv.led_on("LED1")
                    if wait_seconds > 2:
                        app_relay.relay_ctl(1,1)
                        time.sleep(wait_seconds - 2)  # 等待到采集时间前2秒
                    print("Starting data collection...")  # 调试信息
                    # print("-------开始采集数据-------")
                    app_relay.relay_ctl(1,1)
                    time.sleep(1)  # 额外等待1秒确保传感器稳定
                    data = collected_data_handler()  
                    data_list = []
                    # print("TF data:",data)
                    power_votage = float(power.power_votage())
                    data_list.append(data['No1'][0]/10)
                    data_list.append(data['No1'][1]/10) 
                    data_list.append(data['No2'][0]/10)
                    data_list.append(data['No2'][1]/10)
                    data_list.append(data['No3'][0]/10)
                    data_list.append(data['No3'][1]/10) 
                    data_list.append(data['No4'][0]/10)
                    data_list.append(data['No4'][1]/10)
                    data_list.append(data['No5'][0]/10)
                    data_list.append(data['No5'][1]/10) 
                    data_list.append(data['No6'][0]/10)
                    data_list.append(data['No6'][1]/10)
                    data_list.append(power_votage)
                    print(data_list)
                # 存储数据到TF卡
                    tf.wirte_to_csv(('VWC01(%)','TEMP01(C)','VWC02(%)','TEMP02(C)',
                                'VWC03(%)','TEMP03(C)','VWC04(%)','TEMP04(C)',
                                'VWC05(%)','TEMP05(C)','VWC06(%)','TEMP06(C)',
                                'power supply(V)'),data_list) 
                     
                #  记录采集时间，避免重复采集
                    last_collection_time = current_time_tuple
                    last_next_time = next_time
                    # 采集完成后等待
                    time.sleep(2) 
                    app_relay.relay_ctl(1,0)
                    led_drv.led_off("LED1")
                    # 低功耗模式
                    # sleep_mode.voltage_3v3(0)
                else:
                    #动态等待时间
                    if wait_seconds > 7:
                        # 如果等待时间较长，分段睡眠
                        time.sleep(min(wait_seconds - 5, 60))  # 留60秒缓冲
                    else:
                        # 等待时间较短，精确睡眠
                        time.sleep(max(wait_seconds - 1, 0.5))  # 留1秒缓冲 
            else:
                # 短暂等待
                time.sleep(1)
        else:
            time.sleep(1)
            collect_flag += 1
            if collect_flag >= max_wait_time *60:
                collect_flag = 0
                uart_proj.set_collect_flag(True)
                collect_flag = 0
        

if __name__ == '__main__':
     main()
